import yaml

from common import constants
from common.util import Util


class ConfigurationFactory:
    __conf_name = constants.CONF_NAME
    __conf_suffix = constants.CONF_SUFFIX
    __conf_encoding = "utf-8"
    __conf = None  # 存储加载的配置

    @classmethod
    def __load_configuration(cls):
        """加载配置并更新全局配置存储"""
        conf_dir = Util.unified_static_path(constants.CONF_DIRECTORY)
        main_conf_path = Util.get_file_path(conf_dir, f'{cls.__conf_name}.{cls.__conf_suffix}')
        with open(main_conf_path, 'r', encoding=cls.__conf_encoding) as file:
            config = yaml.load(file, Loader=yaml.FullLoader)
            p_key = 'profiles'
            a_key = 'active'
            active_profile = config.get(p_key, {}).get(a_key, 'default')
        config_file = f'{cls.__conf_name}-{active_profile}.{cls.__conf_suffix}'
        active_config_path = Util.get_file_path(conf_dir, config_file)
        with open(active_config_path, 'r', encoding=cls.__conf_encoding) as file:
            active_config = yaml.load(file, Loader=yaml.FullLoader)

        # 合并配置
        cls.__conf = cls.__merge_dicts(config, active_config)
        return cls.__conf

    @classmethod
    def get_configuration(cls):
        """获取当前加载的配置"""
        if cls.__conf is None:
            cls.__load_configuration()
        return cls.__conf

    @classmethod
    def refresh_configuration(cls):
        """强制重新加载配置"""
        cls.__conf = None
        # 重新加载配置文件
        return cls.__load_configuration()

    @classmethod
    def __merge_dicts(cls, d1, d2):
        """递归合并两个字典"""
        if d2 is None:
            return d1
        for key in d2:
            if key in d1 and isinstance(d1[key], dict) and isinstance(d2[key], dict):
                cls.__merge_dicts(d1[key], d2[key])
            else:
                d1[key] = d2[key]
        return d1


class ConfigCenter:

    @staticmethod
    def get_file_id():
        return get_conf_value("openai", "file_id")

    @staticmethod
    def get_model():
        return get_conf_value("openai", "model")


def get_conf_value(*keys, default=None):
    """
    通用方法，用于获取配置中的值。
    :param keys: 键路径，支持嵌套键。
    :param default: 默认值，如果配置中不存在键则返回。
    :return: 配置值。
    """
    value = ConfigurationFactory.refresh_configuration() if not constants.AUTOMATIC_LISTENER_ENABLED else ConfigurationFactory.get_configuration()

    for key in keys:
        value = value.get(key, {})
        # 到达最终值时停止
        if not isinstance(value, dict):
            break
    return value if value else default
